package club.dmyang.service;

import club.dmyang.common.enums.RespCodeEnums;
import club.dmyang.common.exception.HyBlogException;
import club.dmyang.common.util.RandomUtil;
import club.dmyang.dao.ArticleMapper;
import club.dmyang.dao.RelatiTagArtiMapper;
import club.dmyang.dao.TagMapper;
import club.dmyang.entity.Article;
import club.dmyang.entity.ArticleWithBLOBs;
import club.dmyang.entity.RelatiTagArti;
import club.dmyang.entity.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Created by brss on 2018/7/14.
 */
@Service("articleService")
public class ArticleServiceImpl implements ArticleService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ArticleServiceImpl.class);

    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private RelatiTagArtiMapper relatiTagArtiMapper;
    @Autowired
    private TagService tagService;
    @Autowired

    //当博客中没有图片的时候(这些图片是从另一个大佬的博客里扒下来的，见谅)
    private static final String[] PICTURES = {
            "http://img.dmyang.club/sysimg/blog_cover_1.jpg",
            "http://img.dmyang.club/sysimg/blog_cover_2.jpg",
            "http://img.dmyang.club/sysimg/blog_cover_3.jpg",
            "http://img.dmyang.club/sysimg/blog_cover_4.jpg",
            "http://img.dmyang.club/sysimg/blog_cover_5.jpg",
            "http://img.dmyang.club/sysimg/blog_cover_6.jpg",
            "http://img.dmyang.club/sysimg/blog_cover_7.jpg",
    };

    /**
     * 查询表中category_id=categoryId的文章的数目
     * (用于删除分类时，判断某分类下是否有文章)
     *
     * @param categoryId
     */
    @Override
    public Integer findNumByCategoryId(Integer categoryId) {
        return articleMapper.selectNumByCategoryId(categoryId);
    }

    /**
     * 查询tag_article表中，tid=tagId的数目
     * (用于删除标签时，判断某标签下是否有文章)
     *
     * @param tagId
     */
    @Override
    public Integer findNumByTagId(Integer tagId) {
        return relatiTagArtiMapper.selectNumByTagId(tagId);
    }

    /**
     * 添加一篇文章(暂时弃用)
     *
     * @param articleWithBLOBs
     * @return
     */
    @Override
    @Transactional
    public boolean addOneArticle(ArticleWithBLOBs articleWithBLOBs) {
        try {
            articleMapper.insert(articleWithBLOBs);
        } catch (Exception e) {
            LOGGER.error("发表文章失败"+e);
            return false;
        }
        return true;
    }
    /**
     * 删除一篇文章（删除时，同时要记得删除tag_article中aid=文章id的记录）
     * 出错就抛出异常，否则没反应
     * @param aid
     * @return
     */
    @Override
    @Transactional//开事物
    public void delOneArticle(Integer aid) {
        relatiTagArtiMapper.deleteByArticleId(aid);
        //int i = 10/0;
        articleMapper.deleteByPrimaryKey(aid);
    }

    /**
     * 更新一篇文章
     *
     * @param articleWithBLOBs
     * @return
     */
    @Override
    public boolean updateOneArticle(ArticleWithBLOBs articleWithBLOBs) {
        int i = articleMapper.updateByPrimaryKeySelective(articleWithBLOBs);
        if (i < 1)
            return false;
        return true;
    }

    /**
     * 查询一篇文章
     *
     * @param aid
     * @return
     */
    @Override
    public ArticleWithBLOBs findOneArticle(Integer aid) {
        ArticleWithBLOBs articleWithBLOBs = articleMapper.selectByPrimaryKey(aid);
        return articleWithBLOBs;
    }

    /**
     * 根据页数(page)和每页容量(limit)查询文章列表
     * 不查询长文本
     *
     * @param page
     * @param limit
     * @return
     */
    @Override
    public List<Article> findArticlesByPageAndLimit(Integer page, Integer limit) {
        if ( page < 1 || limit < 1 ){
            LOGGER.error("page或limit错误！[ page = "+page + "limit = "+limit + "]");
            throw new HyBlogException(RespCodeEnums.GLOBAL_CODE_PARAMETER_ERROR);
        }
        List<Article> articles = articleMapper.selectByStartAndLimit((page - 1) * limit, limit);
        return articles;
    }

    /**
     * 发布一篇文章（发布的时候,还要更新tag,tag_article表）
     *
     * @param article
     * @param tags
     * @return
     */
    @Override
    @Transactional
    public void publishOneArticle(ArticleWithBLOBs article, List<Tag> tags) {
        //插入失败时，自动抛出异常，事物回滚
        //在Mybaits的Mapper中设置了插入后返回主键到article.aid属性中
        //判断article中的urlImg是否为空，为空随机分配一个
        if ( article.getImgUrl() != null && article.getImgUrl().equals("") ){
            article.setImgUrl(PICTURES[RandomUtil.generateOneNum(0,PICTURES.length-1)]);
        }
        articleMapper.insert(article);
        //判断tags中记录是否在数据库中存在
        for (Tag tag : tags) {
            Tag t = tagService.findOneByTname(tag.getTname());
            if ( t == null ){
                //更新tag表：数据库中没有这个标签，则插入
                tagService.addOneTag(tag);
                //更新tag_article表(tagid用刚插入的tag记录的id)
                RelatiTagArti relatiTagArti = new RelatiTagArti();
                relatiTagArti.setAid(article.getAid());
                relatiTagArti.setTid(tag.getTid());
                relatiTagArtiMapper.insert(relatiTagArti);
            }else {
                //tag表中有这条记录，只更新tag_article表
                RelatiTagArti relatiTagArti = new RelatiTagArti();
                relatiTagArti.setAid(article.getAid());
                relatiTagArti.setTid(t.getTid());
                relatiTagArtiMapper.insert(relatiTagArti);
            }
        }
    }

    /**
     * 查询数据库中所有文章的个数
     * （用于分页插件计算一个有多少页）
     *
     * @return
     */
    @Override
    public int findAllNums() {
        return articleMapper.selectAllNum();
    }

    /**
     * 更新一篇文章（更新时还要更新tag,tag_article表）
     *
     * @param article
     * @param tags
     */
    @Override
    @Transactional
    public void updateOneArticle(ArticleWithBLOBs article, List<Tag> tags) {
        //操作失败时，自动抛出异常，事物回滚
        //在Mybaits的Mapper中设置了插入后返回主键到article.aid属性中
        //判断article中的urlImg是否为空，为空随机分配一个
        if ( article.getImgUrl() != null && article.getImgUrl().equals("") ){
            article.setImgUrl(PICTURES[RandomUtil.generateOneNum(0,PICTURES.length-1)]);
        }
        articleMapper.updateByPrimaryKeySelective(article);
        //删除中间表中所有关于这篇文章的记录,然后以现在的为依据重新插入
        relatiTagArtiMapper.deleteByArticleId(article.getAid());
        //判断tags中记录是否在数据库中存在
        for (Tag tag : tags) {
            Tag t = tagService.findOneByTname(tag.getTname());
            if ( t == null ){
                // 更新tag表：数据库中没有这个标签，则插入
                tagService.addOneTag(tag);
                //更新tag_article表(tagid用刚插入的tag记录的id)
                RelatiTagArti relatiTagArti = new RelatiTagArti();
                relatiTagArti.setAid(article.getAid());
                relatiTagArti.setTid(tag.getTid());
                relatiTagArtiMapper.insert(relatiTagArti);
            }else {
                // tag表中有这条记录
                RelatiTagArti relatiTagArti = new RelatiTagArti();
                relatiTagArti.setAid(article.getAid());
                relatiTagArti.setTid(t.getTid());
                relatiTagArtiMapper.insert(relatiTagArti);
            }
        }
    }
}
